/*
 mol2 File Parser and SQL Generator
 ----------------------------------
 
 Created By: Ryan Edwards-Crewe
 
 Last Modified: Feb 24, 2010
 
 Description:
	This is a parser for the mol2 file format. It generates SQL statements
	so the the data can be inserted into a database.
 
 Caveats:
	This is a one pass solution. Depending on the size of your data file
	be sure that you computer can has enough diskspace to produce the rulting
	file wich will be about 42% larger than your original file.
	
	If you plan to use the produced .sql script outside of the command then
	you may need to disable the start transaction and commit lines. Since these
	can interfere with ODBC/JDBC client connections with an sql server.
 */

#include <iostream>
#include <fstream>
#include <string>
#include <list>

#include "Compound.h"

using namespace std;

string getSectionHeading( char&, FILE* );


int main (int argc, char * const argv[]) {
	
	FILE * fPtr;
	FILE * ofPtr;
	
	if (!(ofPtr = fopen("mol2Data.sql", "w"))) {
		cout << "File nah deh!" << endl;
	}
	
	fPtr = fopen ("Pubchem-DrugLikeWithF-Nov132009.mol2" , "r");
	
	if (fPtr == NULL) {
		perror ("\tError opening file");
		exit(EXIT_FAILURE);
	}
	
	char ch;
	int counts[3]; // atoms, bonds, substructs
	
	string heading;
	list<Compound> CompoundList;
	
	Compound CMPD;

	while((ch = fgetc(fPtr)) != EOF){
		
		switch (ch) {
			case '@':
				while (ch != '>') {
					ch = fgetc(fPtr);
				}
				heading = getSectionHeading(ch, fPtr);
				if (heading == "MOLECULE") {
					CMPD.addMoleData( ch, fPtr );
					counts[0] = CMPD.getAtomCount();
					counts[1] = CMPD.getBondCount();
					counts[2] = CMPD.getSubsCount();
					
					cout <<"\n-- "<< CMPD.getCID() << " --"<< endl;					
					cout << "SECTION:" << heading << endl;
				}
				else if (heading == "ATOM") {
					cout << "SECTION:" << heading << endl;
					for (int i=1; i <= counts[0]; i++)
						if ( CMPD.addAtomData( ch, fPtr ) == -1 )
							cout << "ERROR ON @<TRIPOS>ATOM with CID: " << CMPD.getCID() << "Item: " << i << endl;
				}
				else if (heading == "BOND") {
					cout << "SECTION:" << heading << endl;
					for (int i=1; i <= counts[1]; i++)
						if ( CMPD.addBondData( ch, fPtr ) == -1 )
							cout << "ERROR ON @<TRIPOS>BOND with CID: " << CMPD.getCID() << "Item: " << i << endl;
				}
				else if (heading == "SUBSTRUCTURE") {
					cout << "SECTION:" << heading << endl;
					for (int i=1; i <= counts[2]; i++) {
						if ( CMPD.addSubsData( ch, fPtr ) == -1 ) 
							cout << "ERROR ON @<TRIPOS>SUBSTRUCTURE with CID: " << CMPD.getCID() << "Item: " << i << endl;
					}
					CMPD.writeInsertStatement(ofPtr);
					CMPD.clearCompound();
				}
				else {
					perror("\tError in file format: ");
					cout << "@<TRIPOS>" << heading << " incomplete\n" <<  endl;
					exit(EXIT_FAILURE);
				}
				
				break;
				
			default:
				break;
		}
		
	}
	
	fclose(ofPtr);
	fclose(fPtr);
	return 0;
}

string getSectionHeading( char& ch, FILE* fp ) {
	string HEAD;
	
	while ((ch != '\n') || (ch != '\r')) {
		ch = fgetc(fp);
		if (ch == '\r') break;
		HEAD = HEAD + ch;
	}
	
	return HEAD;
}